package com.jichangxiu.framework.security.filter;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.jichangxiu.common.entity.bo.Payload;
import com.jichangxiu.common.entity.bo.SecurityUser;
import com.jichangxiu.common.utils.CacheUtils;
import com.jichangxiu.common.utils.ServletUtils;
import com.jichangxiu.common.utils.TokenUtils;
import com.jichangxiu.framework.security.entity.AuthToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

/**
 * AuthFilter:
 *
 * @author Jcx
 * @create 2023-04-04 13:43
 */
@Slf4j
@Component
public class AuthFilter extends OncePerRequestFilter {

    @Resource
    private TokenUtils tokenUtils;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setAttribute("startTime", System.nanoTime());
        log.info("当前时间：" + DateUtil.formatDateTime(new Date()));
        log.info("请求地址：" + request.getRequestURI());
        try {
            // 获取用户的权限等信息
            long startTime = System.nanoTime();
            String jti = tokenUtils.getJti(request);
            Payload<SecurityUser> payload = (Payload<SecurityUser>) CacheUtils.get(jti);
            if (ObjectUtil.isEmpty(payload)) {
                payload = tokenUtils.getPayload(request);
                if (ObjectUtil.isNotEmpty(payload)) {
                    log.info("向本地缓存中设置登录用户信息");
                    CacheUtils.set(jti, payload);
                }
            }
            if (ObjectUtil.isNotEmpty(payload)) {
                log.info("当前的登录用户：" + payload.getUserInfo().getUsername());
                log.info("当前登录用户的jti：" + payload.getJti());
                ServletUtils.setSecurityUser(payload.getUserInfo());
                // 构建 UsernamePasswordAuthenticationToken 这里密码为 null，是因为提供了正确的 JWT,实现自动登录
                AuthToken authToken = new AuthToken(payload.getUserInfo().getRecord().getStr("tenantName"),
                        payload.getUserInfo().getRecord().getStr("username"),
                        payload.getUserInfo().getRecord().getStr("password"),
                        payload.getUserInfo().getAuthorities());
                SecurityContextHolder.getContext().setAuthentication(authToken);
            }
        } catch (Exception e) {
            log.warn("未登录，或 token 已过期");
        } finally {
            chain.doFilter(request, response);
        }
    }

}
